package tum0r.webengine.models.core

import tum0r.webengine.config.ApplicationConfig
import tum0r.webengine.config.BaseConfig
import tum0r.webengine.config.SessionConfig
import tum0r.webengine.enums.EConfigType
import tum0r.webengine.enums.ERequestMethod
import tum0r.webengine.extension.check
import tum0r.webengine.extension.checkBlank
import tum0r.webengine.extension.checkNull
import tum0r.webengine.extension.checkNullOrBlank
import java.net.InetAddress

/**
 * 说明: 请求信息处理和返回结果
 *
 * 创建者: tum0r
 *
 * 时间: 2021/8/22 14:24
 *
 * @param[response] 响应头
 * @param[result] 结果
 */
data class Action<T>(val response: LinkedHashMap<String, Any>, var result: T?) {
    init {
        addResponseHeader("Protocol", "HTTP/1.1")
        addResponseHeader("State", "200 OK")
        addResponseHeader("Content-Type", "text/plain; charset=utf-8")
        addResponseHeader("Content-Length", 0)
        addResponseHeader("Powered-By", "WebEngine")
        addResponseHeader("Copy-Right", "scr1pt")
        if (BaseConfig.isState(EConfigType.RETURN_SERVER_NAME)) addResponseHeader("Server", ApplicationConfig.SERVER_NAME)
    }

    constructor() : this(LinkedHashMap(), null)

    /**
     * 请求信息
     */
    @JvmField
    var request: HttpRequest? = null

    /**
     * HTTP请求方法
     */
    @JvmField
    var requestMethod: ERequestMethod? = null

    /**
     * 远程地址
     */
    @JvmField
    var remoteAddress: InetAddress? = null

    /**
     * 本机地址
     */
    @JvmField
    var localAddress: InetAddress? = null

    /**
     * 设置
     *
     * @param[request] 请求信息
     */
    fun setRequest(request: HttpRequest) {
        this.request = request
        requestMethod = ERequestMethod.valueOf(request.headers["RequestMethod"]!!)
        if (BaseConfig.isState(EConfigType.RETURN_SESSION)) addResponseHeader("Set-Cookie", "${SessionConfig.SESSION_NAME}=${request.session!!.ID};${response.getOrDefault("Set-Cookie", "")}")
    }

    /**
     * 添加响应头，已存在则会覆盖
     *
     * @param[key] 响应头键
     * @param[value] 响应头值
     */
    fun addResponseHeader(key: String, value: Any) = value.also { response[key] = it }

    /**
     * 获取响应头字符串
     */
    fun getResponseHeadersString(): String {
        val result = StringBuilder()
        val iterator = response.keys.iterator()
        result.append(response[iterator.next()]).append(" ").appendLine(response[iterator.next()])
        while (iterator.hasNext()) {
            val key = iterator.next()
            result.append(key).append(": ").appendLine(response[key])
        }
        return result.appendLine().toString()
    }

    /**
     * flag为true时抛出错误信息
     */
    @JvmOverloads
    fun check(flag: Boolean, message: String, code: Int = 440) = message.check(flag, code)

    /**
     * 检查字符串是否为空，若是则抛出错误信息
     *
     * @param[message] 抛出的错误信息
     * @param[values] 被检查的字符串
     */
    fun checkBlank(message: String, vararg values: String) = message.checkBlank(*values)

    /**
     * 检查对象是否为空，若是则抛出错误信息
     *
     * @param[message] 抛出的错误信息
     * @param[values] 被检查的对象
     */
    fun checkNull(message: String, vararg values: Any?) = message.checkNull(*values)

    /**
     * 检查字符串是否为null或空，若是则抛出错误信息
     *
     * @param[message] 抛出的错误信息
     * @param[values] 被检查的字符串
     */
    fun checkNullOrBlank(message: String, vararg values: String?) = message.checkNullOrBlank(*values)

    /**
     * 返回数据
     */
    fun callback(result: T?) {
        this.result = result
    }
}